﻿#include "metacreator.h"

class StandardMetaInfoBackend :public IMetaInfoBackend {

	StandardMetaInfoBackend(IMetaInfoBackend* SuperClass , __StandardMetaInfoHelper::ClassData _data):IMetaInfoBackend(SuperClass) {
		this->data = _data;
	}

	~StandardMetaInfoBackend() {
		int i = 0;
		i++;
	}

	virtual ClassFlag GetClassFlag() const {
		return data.flag;
	}
	virtual int GetSize() const {
		return data.Size;
	}
	virtual std::string GetClassName() const {
		return data.className;
	}

	virtual int NumberOfConstructor() const {
		return data.m_ConstructorInfo.size();
	};
	virtual MetaConstructorInfo GetConstructorInfo(int index) const {

		auto & con = data.m_ConstructorInfo[index];

		MetaConstructorInfo ret;

		ret.ArgTypes = con.ArgTyps;
		ret.Infos = con.Infos;

		return ret;
	};
	virtual void Create(void* buffer, int index, const void** args) const {
		
		auto & cons = data.m_ConstructorInfo[index];

		cons.con(buffer, args);
	};
	virtual void Destory(void* target) const {
		data.Destory(target);
	}

	virtual std::vector<std::string> GetClassInfos() const {
		return data.ClassInfo;
	};

	virtual int NumberOfFunctions() const {
		return data.m_FunctionInfo.size();
	}

	virtual MetaFunctionInfo GetFunctionInfo(int index) const {
		auto& fun = data.m_FunctionInfo[index];
		MetaFunctionInfo ret;

		ret.ArgTypes = fun.ArgTyps;
		ret.Infos = fun.Infos;
		ret.Name = fun.Name;
		ret.ReturnType = fun.ReturnType;

		return ret;
	}
	virtual void InvokeMetaFunction(void* target, int index, void* Ret, const void** args) const {
		
		auto& fun = data.m_FunctionInfo[index];
		fun.fun(target, args, Ret);
	}

	virtual int NumberOfSignals() const {
		return data.m_SignalInfos.size();
	}
	virtual MetaSignalInfo GetSignalInfo(int index) const {
		auto& signal = data.m_SignalInfos[index];
		MetaSignalInfo ret;
	
		ret.ArgTypes = signal.ArgTypes;
		ret.Infos = signal.Infos;
		ret.Name = signal.Name;

		return ret;
	}
	virtual GenericSignal* GetSignal(void* target,int index) const {
		auto& signal = data.m_SignalInfos[index];
		return signal.getter(target);
	}

	virtual int NumberOfPropertys() const {
		return data.m_PropertyInfos.size();
	}
	virtual MetaPropertyInfo GetPropertyInfo(int index) const {
		auto& prop = data.m_PropertyInfos[index];

		MetaPropertyInfo ret;
		ret.Infos = prop.Infos;
		ret.Name = prop.Name;
		ret.NotifierName = prop.Notifier;
		ret.Readable = prop.getter != NULL;
		ret.Type = prop.Type;
		ret.Writable = prop.setter != NULL;
		ret.flags = prop.flags;

		return ret;
	}
	virtual void ReadProperty(void* target,int index, void* buffer) const {
		auto& prop = data.m_PropertyInfos[index];
		if (prop.getter) {
			const void* param[1] = {};
			prop.getter(target,param, buffer);
		}
	}
	virtual void WriteProperty(void* target,int index , const void* src) const {
		auto& prop = data.m_PropertyInfos[index];
		if (prop.setter) {
			const void* param[1] = { src };
			prop.setter(target, param,NULL);
		}
	}

	virtual bool isCastable() const override {
		return (bool)data.Caster;
	};
	virtual Reflectable* MetaCast(void* target) const override {
		if (data.Caster) {
			return data.Caster(target);
		}
		return NULL;
	};

private:
	__StandardMetaInfoHelper::ClassData data;
	friend class __StandardMetaInfoHelper;
};

IMetaInfoBackend* __StandardMetaInfoHelper::CreateMetaInfo(IMetaInfoBackend* SuperClass, const ClassData& data) {
	auto ret = new StandardMetaInfoBackend(SuperClass, data);
	ret->CalculateCacheData();
	return ret;
}